package io.renren.modules.file.service.impl;

import com.mongodb.client.gridfs.model.GridFSFile;
import io.renren.common.utils.*;
import io.renren.modules.file.dao.SysUploadFileDao;
import io.renren.modules.file.entity.SysUploadFileEntity;
import io.renren.modules.file.entity.UtilContentTypeEntity;
import io.renren.modules.file.service.SysUploadFileService;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Service("sysUploadFileService")
public class SysUploadFileServiceImpl extends ServiceImpl<SysUploadFileDao, SysUploadFileEntity> implements SysUploadFileService {

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<SysUploadFileEntity> page = this.selectPage(
                new Query<SysUploadFileEntity>(params).getPage(),
                new EntityWrapper<>()
        );
        return new PageUtils(page);
    }

    @Override
    @Transactional
    public R saveFile(MultipartFile request, SysUploadFileEntity file) throws Exception {
        //增加文件头信息对比，防止用户恶意篡改文件名后缀
        UtilContentTypeEntity utilContentTypeEntity = checkHead(request);
        if (utilContentTypeEntity == null) {
            return R.error("检测到文件异常或者文件类型不允许");
        }
        file.setFileType(utilContentTypeEntity.getTypeName());
        Document metadata = new Document();
        metadata.put("head", utilContentTypeEntity.getHead());
        metadata.put("suffix", utilContentTypeEntity.getSuffix());
        GridFSFile gridFSFile = MongodbUtils.saveFile(request, metadata);
        String objectId = gridFSFile.getObjectId() + "";
        file.setFilename(gridFSFile.getFilename());
        file.setSuffix(utilContentTypeEntity.getSuffix());
        file.setDbName("test");
        file.setChunkSize(gridFSFile.getChunkSize());
        file.setChunkSize(gridFSFile.getChunkSize());
        file.setMd5(gridFSFile.getMD5());
        file.setIsDelete(0);
        file.setUploadDate(gridFSFile.getUploadDate());
        file.setLength(gridFSFile.getLength());
        file.setHead(utilContentTypeEntity.getHead());
        file.setObjectId(objectId);
        this.insert(file);
        return R.ok().put("data", file);
    }

    @Override
    /**
     * 删除文件
     * @return
     */
    public R deleteFile(String objectId) {
        if (MongodbUtils.deleteFile(objectId)) {
            return R.ok();
        }
        return R.error("文件删除失败或者已经删除。");
    }

    @Override
    /**
     * 下载word文件
     * imageMap 如果有图片，把图片放入里面
     * fileTitle 标题
     * ftlFile 模板
     * @return
     */
    public R downLoadWord(Map<String, Object> inMap, HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (inMap.get("fileTitle") == null) {
            return R.error("标题没有输入");
        }
        if (inMap.get("ftlFile") == null) {
            return R.error("没有指定模板");
        }
        if (inMap.get("imageMap") != null) {
            Map<String, String> imageMap = MongodbUtils.getImageInputStreamBatch((HashMap<String, String>) inMap.get("imageMap"));
            inMap.remove("imageMap");
            inMap.putAll(imageMap);
        }
        WordUtils.exportMillCertificateWord(inMap.get("fileTitle") + "", request, response, inMap);
        return null;
    }

    /**
     * 检验文件头是否匹配
     *
     * @param request
     * @return
     */
    private UtilContentTypeEntity checkHead(MultipartFile request) {
        String head = FileUtil.getFileHeader(request);//获取头文件
        String fileName = request.getOriginalFilename();
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        UtilContentTypeEntity utilContentTypeEntity = redisUtils.getFromHash(ConstantUtils.CONTENT_TYPE, suffix, UtilContentTypeEntity.class);
        if (utilContentTypeEntity == null) {
            return null;
        }
        if (!utilContentTypeEntity.getContentType().equals(request.getContentType() + "")
                || !head.equals(utilContentTypeEntity.getHead() + "")) {
            return null;
        }
        return utilContentTypeEntity;
    }

}
